锁定系统
主要实现锁敌的效果 ——
- 搜索附近目标
- 锁定目标
- 解除锁定
- 在多个目标之间切换
- 锁定时让角色身体朝向目标
- 锁定时让相机视角朝向目标
代码设计
ISakuraLockOnTargetInterface 定义可被锁定的对象 Dummy 具体实现了接口,表示可被锁定的对象 USakuraLockOnComponent 具体锁敌人的行为,比如如何调整搜索范围、查找最优的锁定对象、控制Character的部分特性等
- 单一职责,把职责划分开,Character 拥有组件
- 依赖倒置
- 可被锁定的对象实现接口
- 组件依赖接口
- 实现解耦
部分实现
IsValidLockOnTarget
IsValidLockOnTarget(const AActor* Candidate) const;
- Candidate 必须有效
- 不能是自己
- 必须有 LockOnTarget Tag,或者实现 LockOnTargetInterface
- 如果实现接口,调用 CanBeLockedOn() 判断是否可以锁定
其他规则亦可在之后加入
FindBestTarget
FindBestTarget(const TArray<AActor*>& Candidates) const;
判定最佳目标,目前的设定为
- 在锁定视角范围内
- 简单的通过点乘运算
FVector::DotProduct(ViewForward, ToTargetDir)检查夹角即可
- 简单的通过点乘运算
- 满足上述条件的距离最近者
角色控制
在锁定的时候组件开始 Tick,更新 ActorRotation 和 ControlRotation
- ActorRotation 角色身体朝向
- ControlRotation 玩家控制视角 / aiming 方向
通过平滑旋转 FMath::RInterpTo(...) 到设定的方向
同时注意,Movement->bOrientRotationToMovement = true; 的含义是角色朝移动方向旋转,这是在正常的跑图情况下应当设置成 True,在锁定的情况下设置成 False,手动控制角色朝向,使得其始终朝向目标。